﻿/*********************************************************************************
**                                                                              **
**  Copyright (C) 2024-2025 LiLong                                              **
**  This file is part of OpenVisaApplication.                                   **
**                                                                              **
**  OpenVisaApplication is free software: you can redistribute it and/or modify **
**  it under the terms of the GNU General Public License as published by        **
**  the Free Software Foundation, either version 3 of the License, or           **
**  (at your option) any later version.                                         **
**                                                                              **
**  OpenVisaApplication is distributed in the hope that it will be useful,      **
**  but WITHOUT ANY WARRANTY; without even the implied warranty of              **
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               **
**  GNU General Public License for more details.                                **
**                                                                              **
**  You should have received a copy of the GNU General Public License           **
**  along with OpenVisaApplication. If not, see <https://www.gnu.org/licenses/>.**
**********************************************************************************/
#include "UpdateDialog.h"

#include <QCustomUi/QCtmFile.h>
#include <QCustomUi/QCtmMessageBox.h>

#include <QApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QProcess>
#include <QStandardPaths>
#include <QTimer>

struct UpdateDialog::Impl
{
    QUrl downloadUrl;
    QNetworkAccessManager* mgr;
    QNetworkReply* reply { nullptr };
};

UpdateDialog::UpdateDialog(QWidget* parent) : QCtmDialog(parent), m_impl(std::make_unique<Impl>())
{
    ui.setupUi(centralWidget());
    connect(ui.updateBtn, &QPushButton::clicked, this, &UpdateDialog::onUpdateBtn);
    m_impl->mgr = new QNetworkAccessManager(this);
    ui.progressBar->setVisible(false);
}

UpdateDialog::~UpdateDialog() {}

void UpdateDialog::setDatas(const QString& version, const QString& description, const QString& downloadUrl, bool isLatest)
{
    ui.version->setText(version);
    ui.description->setMarkdown(description);
    m_impl->downloadUrl = downloadUrl;
    ui.updateBtn->setVisible(!isLatest);
    setWindowTitle(isLatest ? u8"已经是最新版本" : u8"发现新版本");
}

void UpdateDialog::onUpdateBtn()
{
    if (m_impl->downloadUrl.isEmpty())
    {
        QCtmMessageBox::critical(this, u8"错误", u8"获取下载地址失败!");
        return;
    }
    if (!m_impl->reply)
    {
        ui.progressBar->setVisible(true);
        m_impl->reply = m_impl->mgr->get(QNetworkRequest(m_impl->downloadUrl));
        connect(m_impl->reply,
                &QNetworkReply::downloadProgress,
                this,
                [this](qint64 bytes, qint64 total)
                {
                    ui.progressBar->setRange(0, total);
                    ui.progressBar->setValue(bytes);
                });
        connect(m_impl->reply, &QNetworkReply::finished, this, &UpdateDialog::onFinished);
        ui.updateBtn->setText(u8"取消");
    }
    else
    {
        auto rep      = m_impl->reply;
        m_impl->reply = nullptr;
        rep->abort();
        rep->deleteLater();
        ui.updateBtn->setText(u8"更新");
    }
}

void UpdateDialog::onFinished()
{
    ui.progressBar->setVisible(false);
    if (!m_impl->reply)
        return;
    auto data = m_impl->reply->readAll();
    m_impl->reply->deleteLater();
    auto savePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + m_impl->downloadUrl.fileName();
    if (!QCtmFile::save(savePath, data))
    {
        QCtmMessageBox::critical(this, u8"错误", u8"保存安装文件失败!");
        return;
    }
    QProcess::startDetached(savePath);
    QTimer::singleShot(2000,
                       []()
                       {
                           qApp->setProperty("_force_quit", true);
                           qApp->quit();
                       });
}
